package com.campus.customer.controller;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.campus.common.bean.common.Resp;
import com.campus.customer.bean.user.CustomerOpenidToDeliveryUserBean;
import com.campus.customer.service.WechatAuthService;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Map;

@RestController
@RequestMapping("/wechat")
public class WechatAuthController {
    @Autowired
    private WechatAuthService wechatAuthService;

    @Value("${wechat.appid}")
    private String appid;

    @Value("${wechat.secret}")
    private String secret;



    /**
     * 微信小程序静默登录
     * @param params 包含微信登录code
     * @return token和用户信息
     */
    @PostMapping("/wxLogin")
    public Resp wxLogin(@RequestBody Map<String, String> params) {
        String code = params.get("code");
        if (code == null || code.isEmpty()) {
            return Resp.error("code不能为空");
        }
        
        return wechatAuthService.wxLogin(code);
    }

    /**
     * 刷新token接口
     * @param params 包含refreshToken
     * @return 新accessToken和refreshToken
     */
    @PostMapping("/refreshToken")
    public Resp refreshToken(@RequestBody Map<String, String> params) {
        String refreshToken = params.get("refreshToken");
        if (refreshToken == null || refreshToken.isEmpty()) {
            return Resp.error("refreshToken不能为空");
        }
        return wechatAuthService.refreshToken(refreshToken);
    }

    /**
     * 获取微信手机号（废弃）
     * @param request
     * @return 手机号码
     */
    @Deprecated
    @PostMapping("/getPhoneNumberOld")
    public Resp<String> getPhoneNumberOld(@RequestBody WeChatRequest request) {
        // 1. 参数校验
        if (StrUtil.hasBlank(request.getCode(), request.getEncryptedData(), request.getIv())) {
            return Resp.error("参数缺失：code/encryptedData/iv");
        }

        // 2. 使用Hutool调用微信code2Session接口
        String url = StrUtil.format(
                "https://api.weixin.qq.com/sns/jscode2session?appid={}&secret={}&js_code={}&grant_type=authorization_code",
                appid, secret, request.getCode()
        );

        try {
            // Hutool发送GET请求并自动处理响应
            String response = HttpUtil.get(url);
            JSONObject sessionData = JSONUtil.parseObj(response);

            // 3. 检查微信接口返回错误
            if (sessionData.containsKey("errcode")) {
                return Resp.error("微信接口错误: " + sessionData.getStr("errmsg"));
            }

            // 4. 解密手机号
            String phoneNumber = decryptPhoneNumber(
                    request.getEncryptedData(),
                    request.getIv(),
                    sessionData.getStr("session_key")
            );

            return Resp.success(phoneNumber);

        } catch (Exception e) {
            return Resp.error("解密失败: " + e.getMessage());
        }
    }

    /**
     * 解密手机号的方法
     */
    private String decryptPhoneNumber(String encryptedData, String iv, String sessionKey) throws Exception {
        byte[] encryptedDataBytes = Base64.getDecoder().decode(encryptedData);
        byte[] ivBytes = Base64.getDecoder().decode(iv);
        byte[] sessionKeyBytes = Base64.getDecoder().decode(sessionKey);

        // AES解密
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        SecretKeySpec keySpec = new SecretKeySpec(sessionKeyBytes, "AES");
        IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);
        cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
        byte[] decryptedBytes = cipher.doFinal(encryptedDataBytes);
        JSONObject phoneInfo = JSONUtil.parseObj(new String(decryptedBytes, StandardCharsets.UTF_8));
        return phoneInfo.getStr("purePhoneNumber"); // 或 "phoneNumber" 根据微信版本
    }

    /**
            * 简化版DTO（使用Lombok）
            */
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public static class WeChatRequest {
        private String code;
        private String encryptedData;
        private String iv;
    }


    /**
     * 获取微信手机号
     * @param code
     * @return
     */
    @GetMapping("/getPhoneNumber")
    public Resp<String> getWechatPhoneNumber(@RequestParam String code) {
        String phone = wechatAuthService.getWechatPhoneNumber(code);
        return Resp.success(phone);
    }

    /**
     * 配送员获取顾客端openid接口
     * 用于解决微信支付分账问题
     * @param bean 包含配送员openid和微信登录code
     * @return 操作结果
     */
    @PostMapping("/saveCustomerOpenidToDeliverUser")
    public Resp saveCustomerOpenidToDeliverUser(@RequestBody @Validated CustomerOpenidToDeliveryUserBean bean) {
        String code = bean.getCode();
        String deliveryOpenid = bean.getDeliveryOpenid();

        return wechatAuthService.saveDeliveryCustomerOpenid(code, deliveryOpenid);
    }

}